﻿Imports MySql.Data.MySqlClient
Public Class EwinsynServiceHandler
    Private Shared instance As ewinsync.EwinsynServiceHandler
    Public Const SERVICE_STARTED As Integer = 1
    Public Const SERVICE_STOPPED As Integer = 0
    Public Const SERVICE_STARTING As Integer = 2
    Public Const SERVICE_STOPING As Integer = 3
    Public Const SERVICE_ERROR As Integer = 4
    Private errors As String = ""
    Private faulty As Boolean
    Private status As Integer = 0
    Private log As ActivityLogger
    Private myh As MySqlHandler
    Dim wch As IWinccHandler
    Dim ewser As EwinSyncService
    Dim WithEvents launchtimer As Timers.Timer
    Sub New()
        log = ActivityLogger.getInstance
        launchtimer = New Timers.Timer
    End Sub

    Protected Overrides Sub Finalize()

    End Sub

    Public Shared Function getInstance() As EwinsynServiceHandler
        If (IsNothing(instance)) Then instance = New EwinsynServiceHandler
        Return instance
    End Function

    Public Function startService() As Integer
        status = SERVICE_STARTING
        myh = MySqlHandler.getInstance
        errors = ""
        'check mysql database. if not true log and exit and show error link
        If (Not checkMysqlDatabase()) Then
            errors = "Service not started due to the following reasons" + vbCrLf + errors
            status = SERVICE_ERROR
            Return status
        End If
        'check winccdatabase

        wch = getWinCCHandler()
        If (Not checkWinCc()) Then
            errors = "Service not started due to the following reasons" + vbCrLf + errors
            status = SERVICE_ERROR
            Return status
        End If
        'check table mapping
        Dim tm As ewindt.DtTableMappingDataTable = myh.getTablesMapping
        Dim cm As ewindt.DtColumnMappingDataTable = myh.getColumnMapping
        If (IsNothing(tm)) Then
            tm = New ewindt.DtTableMappingDataTable
            cm = New ewindt.DtColumnMappingDataTable
        End If
        If (Not checkMapping(tm, cm)) Then
            errors = "Service not started due to the following reasons" + vbCrLf + errors
            status = SERVICE_ERROR
            Return status
        End If
        'check if the tables exist and have the same value
        If (Not myh.checkAnCompareMapping(tm, cm)) Then
            'add cumulative error and return
            errors = "Service not started due to the following reasons" + vbCrLf + myh.Errors
            status = SERVICE_ERROR
            Return status
        End If
        'enable timer
        ewser = New EwinSyncService(myh, wch)

        status = SERVICE_STARTED
        Return status
    End Function

    Public Sub stopService()
        status = SERVICE_STOPING
        launchtimer.Stop()
        launchtimer.Enabled = False
        status = SERVICE_STOPPED
    End Sub

    Public Sub restartService()
        If (status = SERVICE_STARTED) Then stopService()
        startService()
    End Sub
    Public Function getServiceStatus() As Integer
        Return status
    End Function
    Public Function isFaulty() As Boolean
        Return faulty
    End Function
    Private Sub dolog(ByVal msg As String, ByVal sev As String)
        log.log(commons.MOD_SERVICEHANDLER, msg, sev)
    End Sub
    Private Function checkMysqlDatabase() As Boolean
        Dim mu As New MySqlUtilities(MySqlHandler.getInstance().mysqlconf)
        If (Not mu.databaseExist) Then
            If (mu.MysqErrorcode = MySqlErrorCode.UnknownDatabase) Then
                If (Not My.Settings.resetmysql) Then
                    doCumulativeError("Database " + mu.mysqldb + " not found on the specified Adress. Please verify Setting and check 'Reset database' to install it into the specified server", ActivityLoggerConf.LOGLEVEL_ERROR)
                    Return False
                Else
                    If (Not myh.installDatabase) Then
                        doCumulativeError("Unable to instal " + mu.mysqldb + " database due to the following error ", ActivityLoggerConf.LOGLEVEL_ERROR)
                        doCumulativeError(vbTab + "" + MySqlHandler.getInstance.Errors, ActivityLoggerConf.LOGLEVEL_ERROR)
                        Return False
                    Else

                        My.Settings.resetmysql = False
                    End If
                End If
            Else
                Return False
            End If
        End If
        Return True
    End Function
    Private Function getWinCCHandler() As IWinccHandler
        If (My.Settings.op_isdebug) Then
            Return MockWinccHandler.getInstance
        End If
        Return WinccHandler.getInstance
    End Function
    Private Function checkWinCc() As Boolean
        If (Not wch.testconnection) Then
            doCumulativeError("WinCC server at " + wch.WConfig.Datasource + " is not reacheable due to" + wch.Errors, ActivityLoggerConf.LOGLEVEL_ERROR)
            Return False
        End If
        Return True
    End Function
    Private Function checkMapping(ByRef tm As ewindt.DtTableMappingDataTable, ByRef cm As ewindt.DtColumnMappingDataTable) As Boolean
        If (tm.Rows.Count <= 0) Then
            doCumulativeError("There are no Mapping with WinCC database defined yet. Please set the mapping before running the service", ActivityLoggerConf.LOGLEVEL_OPERATION)
            Return False
        End If

        For Each tr As ewindt.DtTableMappingRow In tm.Rows
            Dim filter As String = cm.idtablemappingColumn.ColumnName + "=" + tr.id.ToString
            Dim cr() As ewindt.DtColumnMappingRow = cm.Select(filter)
            If (cr.Length <= 0) Then
                doCumulativeError("One or more tables are not correctly mapped. Please set the mapping before running the service", ActivityLoggerConf.LOGLEVEL_OPERATION)
                Return False
            End If
        Next
        Return True
    End Function
    Private Sub doCumulativeError(ByVal msg As String, ByVal svt As String)
        errors = errors + vbCrLf + "- " + msg + "(" + svt + ")"
        doLog(msg, svt)
    End Sub
    Private Sub launch()
        Dim nextl As DateTime = Now.AddMinutes(My.Settings.op_importdelay)
        launchtimer.Interval = My.Settings.op_importdelay * 60000
        doLog("Launch Timer started and will fire at " + nextl.ToString("hh:mm:ss"), ActivityLoggerConf.LOGLEVEL_INFO)
        launchtimer.Start()
        'My.Application.DoEvents()
    End Sub
    Private Sub launchtimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles launchtimer.Elapsed
        launchtimer.Stop()
        dolog("import starting", ActivityLoggerConf.LOGLEVEL_INFO)
        StartImport()
    End Sub
    Private Sub StartImport()
        Dim sstart As Object = myh.getLastWinccSync
        Dim start As DateTime = Now.AddMinutes(-1 * My.Settings.op_importdelay)
        If (Not IsNothing(sstart)) Then
            start = CType(sstart, DateTime)
        End If
        Dim endi As DateTime = Now
        ewser.performImport(start, endi)
        myh.updateLastWinccSync(endi)
        doLog("import done", ActivityLoggerConf.LOGLEVEL_INFO)
        launch()
    End Sub
    Public Function getErrors() As String
        Return errors
    End Function
End Class
